package cn.est.controller;

import cn.est.config.WxConfig;
import cn.est.constants.Constants;
import cn.est.constants.Constants.Token;
import cn.est.dto.Result;
import cn.est.exceptions.RedisException;
import cn.est.exceptions.TokenProtectedException;
import cn.est.pojo.Users;
import cn.est.service.TokenService;
import cn.est.service.UsersService;
import cn.est.utils.HttpClientUtil;
import cn.est.utils.RedisUtil;
import cn.est.utils.ResultUtils;
import cn.est.vo.TokenVo;

import cn.est.vo.WxTokenVo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api("wx")
@RestController
@RequestMapping("/api/user")
public class WxController {
    @Autowired
    WxConfig wxConfig;
    @Autowired
    UsersService usersService;

    @Autowired
    TokenService tokenService;

    @Autowired
    RedisUtil redisUtil;

    //1.跳转到二维码页面的接口
    @ApiOperation(value = "wx登录请求",produces="application/json",notes ="wx登录请求")
    @GetMapping("/wxlogin")
    public void redirectwx(HttpServletResponse response) throws IOException {
        StringBuffer url=new StringBuffer("https://open.weixin.qq.com/connect/qrconnect?appid=").
                append(wxConfig.getAppid())
                .append("&redirect_uri=")
                .append(URLEncoder.encode("http://localhost:8080/est/api/user/callback"))
                .append("&response_type=code&scope=snsapi_login&state=hellowx#wechat_redirect");
        System.out.println(url.toString());
        response.sendRedirect(url.toString());
    }

    //2.用户授权后页面回调的接口
    @GetMapping("/callback")
    public Result callback(String code, String state){
        if (state==null||!state.equals("hellowx")){
            ResultUtils.returnFail("非法请求");
        }
        //临时票据
        System.out.println(code);
        StringBuffer stringBuffer=new StringBuffer("https://api.weixin.qq.com/sns/oauth2/access_token?appid=");
        stringBuffer.append(wxConfig.getAppid());
        stringBuffer.append("&secret=");
        stringBuffer.append(wxConfig.getAppsecret());
        stringBuffer.append("&code=");
        stringBuffer.append(code);
        stringBuffer.append("&grant_type=authorization_code");
        String response=HttpClientUtil.doGet(stringBuffer.toString());
        JSONObject jsonObject=JSONObject.parseObject(response);
        System.out.println(jsonObject.getString("access_token"));
        System.out.println(jsonObject.getString("openid"));
        //1.判断接口是否能正确调用获取accesstoken
        if (jsonObject.get("errorCode")!=null){
            //说明调用接口出错
            ResultUtils.returnFail((String) jsonObject.get("errmsg"), (String) jsonObject.get("errorCode"));
        }
        //2.判断当前openId是否存在数据库中，若不存在则需要插入数据实现注册功能
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("openId",(String) jsonObject.get("openid"));
       List<Users> usersList =usersService.getUsersListByMap(map);
       Users users=null;
        if (usersList==null||usersList.size()==0){
            users=new Users();
            users.setOpenId((String) jsonObject.get("openid"));
            users.setIsAuthentication(0);
            users.setCreatdTime(new Date());
            users.setIsDelete(0);
            usersService.qdtxAddUsers(users);
        }else {
            users=usersList.get(0);
        }
        //3.生成本站的token，保存用户登录信息
        TokenVo tokenVo=tokenService.genenrateToken(users);
        //4.保存token到redis中
        tokenService.saveToken(tokenVo.getToken(),users);
        //5.返回token
        WxTokenVo wxTokenVo=new WxTokenVo();
        wxTokenVo.setTokenVo(tokenVo);
        wxTokenVo.setAccessToken((String) jsonObject.get("access_token"));
        wxTokenVo.setRefreshToken((String) jsonObject.get("refresh_token"));
        wxTokenVo.setExpiresTime(jsonObject.get("expires_in").toString());
        wxTokenVo.setOpenId((String) jsonObject.get("openid"));
        redisUtil.set("wx:"+tokenVo.getToken(),wxTokenVo, Token.VALID_TIME);
       return ResultUtils.returnDataSuccess(tokenVo);
    }

    @PostMapping("/info")
    public Result getUserInfo(@RequestParam String token) throws UnsupportedEncodingException {
        //1.首先查看reids中是否存在token
        if((Users)redisUtil.get(token)==null){
            return  ResultUtils.returnFail("token无效","20004");
        }
        //2.根据token获取redis中accessToken
        String accessToken=((WxTokenVo)redisUtil.get("wx:"+token)).getAccessToken();
        String openId=((WxTokenVo)redisUtil.get("wx:"+token)).getOpenId();

        //3.拼接url请求，请求用户数据接口
        StringBuffer stringBuffer =new StringBuffer("https://api.weixin.qq.com/sns/userinfo?access_token=");
        stringBuffer.append(accessToken);
        stringBuffer.append("&openid=");
        stringBuffer.append(openId);
        String response= HttpClientUtil.doGet(stringBuffer.toString());
        JSONObject jsonObject= JSONObject.parseObject(response);
         //4.判断返回响应数据是否正确  errcode
        if(jsonObject.get("errcode")!=null){
            return ResultUtils.returnFail(jsonObject.get("errmsg").toString(),jsonObject.get("errcode").toString());
        }
        //5.若数据库中没有这个用户信息则放入数据库中
        Map map = new HashMap<String,Object>();
        map.put("openId",(String) jsonObject.get("openid"));
        List<Users> userList=usersService.getUsersListByMap(map);
        Users user=userList.get(0);
        if(user.getName()==null||user.getName().equals("")){
            String nickname=new String(jsonObject.get("nickname").toString().getBytes("ISO-8859-1"),"UTF-8");
            user.setName(nickname);
            user.setSex(Integer.parseInt(jsonObject.get("sex").toString()));
            user.setFaceUrl(jsonObject.get("headimgurl").toString());
            usersService.qdtxModifyUsers(user);
        }
        //6.返回用户信息
        return  ResultUtils.returnDataSuccess(user);
    }

    //accessToken的置换
    @ApiOperation(value = "微信置换token",produces = "application/json",notes = "微信置换token")
    @PostMapping(value="/refresh")
    public Result refreshWxchatToken(@RequestHeader String token){
        //1.查看token是否有效，token到了置换期，则从新生成token
        TokenVo tokenVo=null;
        try {
            tokenVo=tokenService.refreshToken(token);
        } catch (RedisException e) {
            e.printStackTrace();
        } catch (TokenProtectedException e) {
            e.printStackTrace();
        }
        WxTokenVo wxTokenVo= (WxTokenVo) redisUtil.get("wx:"+token);
        //2.置换accessToken
        StringBuffer stringBuffer=new StringBuffer("https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=");
        stringBuffer.append(wxConfig.getAppid());
        stringBuffer.append("&grant_type=");
        stringBuffer.append("refresh_token");
        stringBuffer.append("&refresh_token=");
        stringBuffer.append(wxTokenVo.getRefreshToken());
        String response=HttpClientUtil.doGet(stringBuffer.toString());
        JSONObject jsonObject = JSON.parseObject(response);
        if(jsonObject.get("error")!=null){
            return ResultUtils.returnFail(jsonObject.get("errmsg").toString(),jsonObject.get("error").toString());
        }
        wxTokenVo.setRefreshToken(jsonObject.get("refresh_token").toString());
        wxTokenVo.setAccessToken(jsonObject.get("access_token").toString());;
        redisUtil.expire("wx:"+token,30);
        redisUtil.set("wx:"+tokenVo.getToken(),wxTokenVo, Constants.Token.WX_VALID_TIME);
        return ResultUtils.returnDataSuccess(tokenVo);
    }
}
